package com.c4p.im.controller;


import com.c4p.im.httpclient.WebClientCache;
import com.c4p.im.session.ISessionStore;
import com.c4p.im.session.IUserChannelStore;
import com.c4p.im.session.IUserNetStore;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.group.ChannelGroupFuture;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.time.Instant;

@RestController
@RequestMapping("/wbs")
@RequiredArgsConstructor
@Slf4j
public class WebSocketController {

    @Resource
    private ISessionStore sessionStore;
    @Resource
    private IUserChannelStore userChannelStore;
    @Resource
    private IUserNetStore userNetStore;

    @PostMapping(value = "/send/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<String> sendMsg(@PathVariable String userId, @RequestBody Message msg) throws Exception{
        log.info("接收到用户: {} 的消息: {}", userId, msg);
        Channel c = null;
        if (( c = userChannelStore.get(userId)) != null){
            if (c.isActive()) {
                TextWebSocketFrame textWebSocketFrame = new TextWebSocketFrame(
                        Instant.now().toEpochMilli() + ":" + msg.getMessage()
                );
                ChannelFuture future = c.writeAndFlush(textWebSocketFrame);
                future.sync();
                log.info("已发送成功");
                return Mono.just("发送给: " + userId);
            }
            else{
                log.info("用户: {} 不在线");
                return Mono.just("已下线");
            }
        }

        //不在当前机器上
        String address = this.userNetStore.get(userId);
        log.info("不在当前机器上，转发至: {} ",  address);

        return WebClientCache.getWebClient(address)
                .post()
                .uri("/wbs/send/{userId}", userId)
                .contentType(MediaType.APPLICATION_JSON)
                .body(Mono.just(msg), Message.class)
                .retrieve()
                .bodyToMono(String.class);
    }


    @RequestMapping(value = "/sendAll", method = RequestMethod.POST)
    public Mono<String> sendMsg(@RequestBody Message msg) throws Exception{
        TextWebSocketFrame textWebSocketFrame = new TextWebSocketFrame(
            Instant.now().toEpochMilli() + ":" + msg.getMessage()
        );

        log.info(msg.getMessage());
        ChannelGroupFuture future = sessionStore.channelGroup().writeAndFlush(textWebSocketFrame);
        future.sync();

        return Mono.just("给所有连接发送消息");
    }


    @Data
    static class Message{
        private String message;
    }


}
